<!doctype html><html lang=cn-zh><head><meta name=generator content="Hugo 0.128.0"><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="IE=edge"><style type=text/css>body{font-family:monospace}</style><title>Hi, I'm Vimiix</title>
<meta name=description content="A blog maintained by Vimiix."><link rel=stylesheet href=/css/style.css><link rel=alternate type=application/rss+xml href=/index.xml title="Hi, I'm Vimiix"><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?7c24231917964240bae97e813810620c",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script></head><body><header>====================<br>== Hi, I'm Vimiix ==<br>====================<div style=float:right;color:gray;font-size:x-large>Get hands dirty.</div><br><p><nav><a href=https://www.vimiix.com/><b>首页</b></a>.
<a href=/posts/><b>文章列表</b></a>.
<a href=/projects/><b>开源项目</b></a>.
<a href=/tags/><b>标签</b></a>.
<a href=/friends/><b>友链</b></a>.
<a href=/about/><b>关于我</b></a>.
<a href=/index.xml><b>RSS</b></a>.</nav></p></header><main><article><h1><a href=https://www.vimiix.com/posts/2019-09-05-mac-sierra-mvim-error/>Mac 升级10.12.6 mvim 打开文件报错</a></h1><b><time>2019.09.05 16:22</time></b>
<a href=/tags/solution>solution</a>
<a href=/tags/mac>mac</a>
<a href=/tags/mvim>mvim</a><div><blockquote><p>当昨天把 Mac 升级了 10.12.6 Sierra 以后，mvim 打开文件的时候就开始报错，使用该方法已解决~</p></blockquote><h3 id=报错信息>报错信息</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
</span></span><span style=display:flex><span>  Referenced from: /usr/local/Cellar/macvim/8.0-146/MacVim.app/Contents/bin/../MacOS/Vim
</span></span><span style=display:flex><span>  Reason: image not found
</span></span><span style=display:flex><span><span style=color:#f92672>[</span>1<span style=color:#f92672>]</span>    <span style=color:#ae81ff>33114</span> abort      mvim -v
</span></span></code></pre></div><a href=https://www.vimiix.com/posts/2019-09-05-mac-sierra-mvim-error/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2019-08-29-how-to-ensure-a-type-implements-an-interface/>Golang如何确保一个类型实现了某个interface</a></h1><b><time>2019.08.29 16:22</time></b>
<a href=/tags/note>note</a>
<a href=/tags/interface>interface</a>
<a href=/tags/golang>golang</a><div><p>在 golang 中，接口（interface）代表一种『协议』存在，它是一个声明了多个方法的集合。</p><p>接口是被隐式实现的，也就是说，我们在开发中定义一个类型（type）的时候，不需要声明这个类型实现了哪个接口。在使用的时候往往通过断言来的 ok-idom 来进行类型判断该类型是否实现了目标接口，放置调用方法失败抛出 panic：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span><span style=color:#66d9ef>if</span> <span style=color:#a6e22e>value</span>, <span style=color:#a6e22e>ok</span> <span style=color:#f92672>:=</span> <span style=color:#a6e22e>AType</span>.(<span style=color:#a6e22e>BInterface</span>) {
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>fmt</span>.<span style=color:#a6e22e>Println</span>(<span style=color:#e6db74>&#34;ok&#34;</span>)
</span></span><span style=display:flex><span>} <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>fmt</span>.<span style=color:#a6e22e>Println</span>(<span style=color:#e6db74>&#34;no&#34;</span>)
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><p>如果断言失败，那么 ok 的值将会是 false,但是如果断言成功 ok 的值将会是 true,同时 value 将会得到所期待的正确的值。</p><a href=https://www.vimiix.com/posts/2019-08-29-how-to-ensure-a-type-implements-an-interface/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2019-03-28-use-hls-to-encrypt-video/>HLS视频加密</a></h1><b><time>2019.03.28 16:22</time></b>
<a href=/tags/note>note</a>
<a href=/tags/video>video</a>
<a href=/tags/encrypt>encrypt</a>
<a href=/tags/ffmpeg>ffmpeg</a>
<a href=/tags/hls>hls</a><div><blockquote><p>最近在做视频管理后台，主要提供点播服务，涉及到需要对视频进行加密处理以防止视频被随意下载。</p><p>调研了一番之后确定使用 HLS(HTTP Live Streaming) 基于 HTTP 的流媒体网络传输协议技术来处理视频。</p><p>所以本文主要记录关于学习 HLS 视频加密技术的笔记</p></blockquote><h3 id=为什么要加密>为什么要加密？</h3><p>简单的说就是：增加获取被加密资源的代价。对于视频这种资源来说，绝对的加密就是不要上线给人看，但那是不可能的，因为提供的服务就是给人看视频，只要上线，别人就可以通过各种手段解密或者简单的录屏的方式来传播，所以目前俩看，不存在绝对的加密。只要让恶意的人获取源视频的代价很大，就可以阻挡绝大多数的不法分子。这样，加密的目的也就基本达到了。</p><a href=https://www.vimiix.com/posts/2019-03-28-use-hls-to-encrypt-video/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2019-01-30-get-video-duration-by-upyun-sdk/>获取存储在又拍云CDN中视频的时长</a></h1><b><time>2019.01.30 16:22</time></b>
<a href=/tags/note>note</a>
<a href=/tags/video>video</a>
<a href=/tags/cdn>CDN</a>
<a href=/tags/%E5%8F%88%E6%8B%8D%E4%BA%91>又拍云</a><div><h3 id=前置条件>前置条件</h3><ul><li><p>可用的账户</p></li><li><p>安装又拍云 Python 版本的 SDK：</p></li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>pip install upyun
</span></span></code></pre></div><p>（官方代码开源地址：<a href=https://github.com/upyun/python-sdk/>https://github.com/upyun/python-sdk/</a> )</p><a href=https://www.vimiix.com/posts/2019-01-30-get-video-duration-by-upyun-sdk/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-11-08-change-git-account-by-script/>快速切换本地Git用户记录</a></h1><b><time>2018.11.08 23:22</time></b>
<a href=/tags/git>git</a>
<a href=/tags/tool>tool</a>
<a href=/tags/bash>bash</a><div><p>现在大部分的科技公司开发模式，都是基于 Git 进行多人协作开发。所以，对于我们每一个开发者来说，Git 的操作就是必不可少的技能了（不是锦上添花，而是必不可少）。对于 Git 的操作，不是本次记录的内容，网上的<a href=https://git-scm.com/book/zh/v1/%E8%B5%B7%E6%AD%A5-Git-%E5%9F%BA%E7%A1%80>教程</a>可以在官网找到。</p><p>今天我想记录一下我本机多用户管理的一点小操作。</p><p>当每进入一家新公司的时候，总会在新公司领到一个新的公司邮箱，基本上这个邮箱也就是你在公司期间进行代码开发的 git 账户。这时候，加上我们平时在 <a href=https://github.com>GitHub</a> 的账户，就会有两个账户需要切换使用。</p><p>下面是我个人的一点小技巧记录，不一定是最好的，但只要自己用着方便就 OK，如果此时看文章的你有好的方法的话，可以请在讨论区交流。</p><a href=https://www.vimiix.com/posts/2018-11-08-change-git-account-by-script/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-10-29-move-qiniuyun-to-alioss-analysis/>从七牛云到阿里云的自动化迁移代码说明</a></h1><b><time>2018.10.29 23:22</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/tool>tool</a><div><p>前几天叙事性的写了<a href=https://vimiix.com/post/2018/10/24/move-qiniuyun-to-alioss/>一篇</a>，有点像日记，这篇分析一下代码逻辑，便于以后回顾。</p><h3 id=工具>工具</h3><ul><li>python3.5</li><li>顺手的 IDE（轻量级推荐<a href=https://code.visualstudio.com/>vscode</a>）</li><li><a href=https://github.com/qiniu/qshell#%E4%B8%8B%E8%BD%BD>qiniu/qshell</a> （本文是基于 mac 系统开发，所以使用 qshell 的 mac 版本，读者请根据自己的系统下载，也可以直接跳至文末，下载本文源码，源码中 tool 文件夹中已经下载好了 mac 下的工具。这个工具只有一步使用到，所以如果只是使用一下，可以不用研究他的所有指令）</li></ul><a href=https://www.vimiix.com/posts/2018-10-29-move-qiniuyun-to-alioss-analysis/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-10-24-move-qiniuyun-to-alioss/>七牛云数据自动迁移到阿里云OSS</a></h1><b><time>2018.10.24 19:22</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/tool>tool</a>
<a href=/tags/migrate>migrate</a><div><h3 id=背景>背景</h3><p>近期收到两封七牛云发来的邮件：</p><blockquote><p>测试域名回收通知</p><p>您的账号 xxx 在七牛云融合 CDN 加速平台有以下测试域名<strong>还剩 7 个自然日会被系统自动回收</strong></p></blockquote><p>由于，我博客所有的图片文件都是存储在七牛云的，这个域名也使用了一年多了，怎么突然要回收呢？</p><p>上网一搜才知道，大概是有什么不法分子之类的，使用七牛云的免费空间传播色情暴力之类的内容，被 Godday 制裁了，现在新申请的 bucket 只能使用一个月，要想绑定域名，还得备案操作。俺这小博客，也就自己玩玩的一个国外服务器，也备不了案啊。</p><p>无奈，看网上很多人都是被回收了才知道自己的图片都访问不了。还好我习惯性的看这些推送邮件，给自己留了一周时间用来备份转移。既然免费的不好用了，微博之类的图床不好迁移，所以就买了一年阿里云的 OSS 服务。</p><p>虽然我的图片还算不是很多，但要是一张一张手动下载再上传到阿里云，也是不小的工作量，而且太浪费时间了。</p><a href=https://www.vimiix.com/posts/2018-10-24-move-qiniuyun-to-alioss/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-10-21-solution-of-pipenv-install-error/>pipenv错误解决:TypeError: "module" object is not callable</a></h1><b><time>2018.10.21 11:22</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/note>note</a>
<a href=/tags/pipenv>pipenv</a>
<a href=/tags/solution>solution</a><div><h3 id=软件版本>软件版本</h3><p>今天在折腾一台新的云主机，所以我在安装环境的时候<code>pip</code>和<code>pipenv</code>都选择安装了最新版本</p><p>（<em>注：正是这两个版本配合才会出现下面的报错，旧版本或以后的新版本的 Pipenv 不会出现</em>）。</p><p>具体如下：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>// pipenv 的版本 2018.7.1
</span></span><span style=display:flex><span>$ pipenv --version
</span></span><span style=display:flex><span>pipenv, version 2018.7.1
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>// pip 的版本 18.1
</span></span><span style=display:flex><span>$ pip --version
</span></span><span style=display:flex><span>pip 18.1 from /usr/bin/python3.6/lib/python3.6/site-packages/pip <span style=color:#f92672>(</span>python 3.6<span style=color:#f92672>)</span>
</span></span></code></pre></div><a href=https://www.vimiix.com/posts/2018-10-21-solution-of-pipenv-install-error/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-10-16-explore-the-problem-of-matplotlib-on-macosx/>macOXS中使用matplotlib遇到的问题及探究</a></h1><b><time>2018.10.16 11:22</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/note>note</a>
<a href=/tags/matplotlib>matplotlib</a>
<a href=/tags/solution>solution</a><div><p>第一次在 mac 系统上使用<strong>matplotlib</strong>库的时候，在执行的时候，往往会遇到下面这样的问题：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>ImportError: Python is not installed as a framework. balabala....
</span></span></code></pre></div><h3 id=解决方案>解决方案</h3><p>当然这个问题很好解决，网上有一搜就会找到如下两种解决方案：</p><h4 id=第一种方案是在系统中设置>第一种方案是在系统中设置</h4><ul><li>假设你已经通过<code>pip install matplotlib</code>安装了 matplotlib，那么在你的根目录中会有一个名为<code>〜/ .matplotlib</code>的目录。</li><li>在这个目录中创建一个<code>matplotlibrc</code>的文件 ,在里面添加一行代码：<code>backend: TkAgg</code>，保存退出即可。</li></ul><p>总结为一行 shell 命令就是：<code>echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc</code></p><p>这种方式可以设定整个系统的 matplotlib 渲染使用的引擎，但是不好的是，代码会变得不可移植，如果服务器很多，我们需要每一台机器都去设置这个参数，这时候就需要使用第二种方案。</p><a href=https://www.vimiix.com/posts/2018-10-16-explore-the-problem-of-matplotlib-on-macosx/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-10-10-dont-just-learn-a-new-language-framework-implement-it-as-a-running-open-source-project/>[译]实践出真知</a></h1><b><time>2018.10.10 23:22</time></b>
<a href=/tags/note>note</a>
<a href=/tags/translation>translation</a><div><p>Aristotle（亚里士多德），希腊著名的哲学家和科学家，曾经说过：“对于那些我们在能做到之前必须学习如何做的事情，我们需要边做边学 (<em>For the things we have to learn before we can do them, we learn by doing them.</em>)”。想象一下，假如你已经读过 3 本关于骑行的书了，然后有人给你一辆自行车并让你骑它，你能骑吗？很显然，答案是“不能”。这无关乎你曾经读了多少关于骑行的书或你看了多少相关视频的事情。它需要你真正骑上一辆自行车，去保持平衡，去学习脚，手和眼睛的协调配合才能掌握的一件事情。学习新技术，新语言或框架同样也是如此。</p><p>如果现在你在想：我都不会某个语言或某个框架，我要怎么去实现这个开源项目呢，那么先停止抱怨。也许你是技术或编程的新手，但你需要知道如何去学习新事物。学习新东西的最好方法就是实践。这篇文章将重点关注普适通用的方法。它会帮助你从我想要学习&rsquo;X&rsquo;到我有一个项目在&rsquo;X&rsquo;运行，所以继续往下看。如果你决定通过做一个项目来学习新东西，那就把它开源吧。Github 是托管你的开源项目的首选服务商。在其上你可以享受很多的免费服务。这篇文章的编写主要面向编程起步者，但对于经验丰富的软件工程师也同样有用。</p><a href=https://www.vimiix.com/posts/2018-10-10-dont-just-learn-a-new-language-framework-implement-it-as-a-running-open-source-project/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-08-27-running-your-flask-application-over-https/>[译]通过HTTPS协议运行你的Flask程序</a></h1><b><time>2018.08.27 17:22</time></b>
<a href=/tags/https>HTTPS</a>
<a href=/tags/ssl>SSL</a>
<a href=/tags/flask>Flask</a>
<a href=/tags/translation>translation</a><div><p>我们在开发 Flask 应用程序时，通常通过运行 Flask 自带的 Web 服务器来开发测试，这个服务器提供了基本的但功能完备的 WSGI 服务器。但开发结束以后，在应用程序上线到生成环境时，有很多不得不考虑的事情，其中之一是我们是否应该要求客户端使用加密连接以增加安全性。</p><p>人们总是问我这个问题，特别是如何在 HTTPS 协议上部署 Flask 服务器。在本文中，我将介绍几种为 Flask 应用程序添加加密的方案，从一个非常简单的可以在五秒内实现，到一个强大的就像我的网站一样可以得到一个 A +评级解决方案（<a href="https://www.ssllabs.com/ssltest/analyze.html?d=blog.miguelgrinberg.com">我的网站的 SSL 分析数据</a>）。</p><a href=https://www.vimiix.com/posts/2018-08-27-running-your-flask-application-over-https/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-08-13-git-best-practice/>Git开发记录-合并多条commit最佳实践</a></h1><b><time>2018.08.13 19:22</time></b>
<a href=/tags/git>git</a><div><h2 id=问题>问题</h2><p>常规的多人基于 GIT 协作开发的时候，都是遵循先 fork 一份主版本代码到自己的账号下面，然后基于本账户的版本，开分支来开发功能或修 Bug，完成以后再讲修改的内容，提交一个完整的 PR 贡献回主版本。</p><p>在本分支上开发的过程中，有时候不得不先提交到自己账号下面的克隆版本中来测试（比如豆瓣的<code>dae pre</code>，无法在本地生成预览，需要提交到远端），我们不能保证一次性提交就做到完美，避免不了会往复的修改后提交，这样的一次次测试用的 commit 属于是冗余的琐碎信息，对于主版本迭代是没有价值的。如果直接在基于该分支提交 PR，甚至被<code>merge</code>到<code>upstream/master</code>主版本中，这些不必要的 commit 信息也会包含进主版本中。这当然不是一个理想的迭代方式。</p><p>现在问题明确以后，就是一个目标：<strong>将这些开发中的所有 commit 都合并为一条有意义的 commit 信息提交给主版本</strong>。</p><a href=https://www.vimiix.com/posts/2018-08-13-git-best-practice/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-07-26-channels2-tutorial/>Django Channels2.0 websocket最佳实践</a></h1><b><time>2018.07.26 02:56</time></b>
<a href=/tags/django>Django</a>
<a href=/tags/channels>Channels</a>
<a href=/tags/websocket>websocket</a><div><p>做 web 后端开发，少不了要和 websocket 打交道。之前写过一篇关于 websocket 的实践文章 &mdash; <a href=https://vimiix.com/post/2018/04/02/python-websocket/>《[python]记录关于 websocket 的原理和使用》</a> ，不过，从 GITHUB 上可以看到，<strong>django-websocket</strong> 这个开源项目俨然已经是一个被放弃了的坑，并且在使用的过程中确实也有很多坑，果断弃之。</p><p>今天想聊的就是目前业界大牛都在推荐的一个框架&ndash;<a href=https://github.com/django/channels>Channels</a>， Channels 是针对 Django 项目的一个增强框架，它可以是的同步的 Django 项目转变为异步的项目。它可以使得 Django 项目不仅支持 HTTP 请求，还可以支持 Websocket, chat 协议，IOT 协议 ，甚至是你自定义的协议，同时也整合了 Django 的 auth 以及 session 系統等等。</p><a href=https://www.vimiix.com/posts/2018-07-26-channels2-tutorial/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-07-17-learn-contextlib/>浅谈Python中的上下文管理</a></h1><b><time>2018.07.18 00:56</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/context>context</a><div><h2 id=with-语法>with 语法</h2><p>平常在写 Python 代码的时候，经常会用到<code>with</code> 来处理一个上下文环境，比如文件的打开关闭，数据库的连接关闭等等。</p><p><code>with</code>语法的使用，需要我们处理的对象实现<code>__enter__</code>和<code>__exit__</code>两个魔术方法来支持。<code>__enter__</code>函数处理逻辑函数之前需要做的事情，并返回操作对象作为<code>as</code>后面的变量，<code>__exit__</code>函数处理当代码离开<code>with</code>代码块以后的事情。</p><p><code>with</code>语法非常方便的让我使用资源并且不用操心忘记后续操作所带来的隐患。</p><a href=https://www.vimiix.com/posts/2018-07-17-learn-contextlib/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-06-05-grokking-algorithms-chapter-7/>《算法图解》读书笔记7-狄克斯特拉算法</a></h1><b><time>2018.07.16 22:20</time></b>
<a href=/tags/algorithm>algorithm</a>
<a href=/tags/python>Python</a>
<a href=/tags/dijkstra>Dijkstra</a><div><h2 id=概念>概念</h2><blockquote><p>狄克斯特拉算法是从一个顶点到其余各顶点的最短路径算法，解决的是有向图中最短路径问题 (该算法不能处理包含负边的图)。主要特点是以起始点为中心向外层层扩展，直到扩展到终点为止。</p></blockquote><a href=https://www.vimiix.com/posts/2018-06-05-grokking-algorithms-chapter-7/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-07-02-wake-up-time/>跳槽</a></h1><b><time>2018.07.02 14:36</time></b>
<a href=/tags/%E7%94%9F%E6%B4%BB>生活</a>
<a href=/tags/%E8%B7%B3%E6%A7%BD>跳槽</a><div>不知不觉，一个月没有写东西。感觉很快，因为没有感觉；但又感觉很慢，因为心理一直在作斗争。
这将近一个月的时间里，我基本没有和圈内的朋友交流，自己都感觉自己像蒸发了一样。这一个月的经过，给我积累了人生的一次重要经验——项目一定要选对人。剩下的就留给时间去消化吧。
今天以后，我将继续恢复日常的上班，学习，记录生活。
今天，北京天气很好。趁着阳光正好，我正式入职豆瓣了。
豆瓣，因为喜欢 python，慕名而来。
希望自己未来可以在这个 python 的"伊甸园"里面茁壮地成长！</div></article><article><h1><a href=https://www.vimiix.com/posts/2018-06-04-python-destructor-and-garbage-collection-notes/>[译]python中垃圾回收和析构函数笔记</a></h1><b><time>2018.06.04 14:36</time></b>
<a href=/tags/gc>GC</a>
<a href=/tags/python>Python</a><div><blockquote><p>紧接上一篇转载的文章<a href=https://vimiix.com/post/2018/06/04/python-magic-methods/>《Python 魔术方法总结》</a>文末提及的英文参考文章，洒家顺手就翻译了一下。方便墙内的同学学习。这篇文章不仅指出了 Python 如何处理垃圾回收，还提到了我们作为程序员不应该只借助现代化 IDE 的函数提示功能去完成代码，应该多去看官方的完整文档，可以知道哪些函数被废弃的，哪些函数在使用时需要注意什么等等一些很重要的信息。话不多说，自己体会，请向下阅读文章吧。</p><p>原文链接：<a href=https://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/>https://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/</a></p></blockquote><p>我很少在 Python 对象中使用析构函数。我猜 Python 的动态特性往往弱化了对析构函数的需求。但是现在，假如我需要在对象被销毁时，或者更确切地说，当程序退出时，要将一些数据写入磁盘。这时我会使用<code>__del__</code> 魔术方法在主要操作的类对象中定义了一个析构函数。但是奇怪的是，这个析构函数自始至终都没有被调用到。不仅在程序退出时没有被调用到，而且我手动使用<code>del</code>删除时也不会被调用。由于这个程序是我前一段时间写的，所有稍微有点不是很熟悉了，这导致我怀疑是我程序中有一个大的 BUG 存在。</p><a href=https://www.vimiix.com/posts/2018-06-04-python-destructor-and-garbage-collection-notes/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-06-04-python-magic-methods/>[转]Python中的魔术方法汇总</a></h1><b><time>2018.06.04 13:20</time></b>
<a href=/tags/magic-method>magic method</a>
<a href=/tags/python>Python</a><div><blockquote><p>这是一篇很不错的总结文章，简单易理解，洒家忍不住要转载收藏一下。</p><p>源文链接：<a href="http://algo.site/?cat=60">http://algo.site/?cat=60</a></p></blockquote><h3 id=基础>基础:</h3><table><thead><tr><th>如果你想…</th><th>所以,你写…</th><th>Python 调用…</th></tr></thead><tbody><tr><td>初始化一个实例</td><td><code>x = MyClass()</code></td><td><code>x.__init__()</code></td></tr><tr><td>作为一个字符串的"官方"表示</td><td><code>repr(x)</code></td><td><code>x.__repr__()</code></td></tr><tr><td>作为一个字符串</td><td><code>str(x)</code></td><td><code>x.__str__()</code></td></tr><tr><td>作为字节数组</td><td><code>bytes(x)</code></td><td><code>x.__bytes__()</code></td></tr><tr><td>作为格式化字符串</td><td><code>format(x, format_spec)</code></td><td><code>x.__format__(format_spec)</code></td></tr></tbody></table><a href=https://www.vimiix.com/posts/2018-06-04-python-magic-methods/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-06-03-grokking-algorithms-chapter-6/>《算法图解》读书笔记6-图以及广度优先搜索</a></h1><b><time>2018.06.03 16:20</time></b>
<a href=/tags/algorithms>algorithms</a>
<a href=/tags/linux>Linux</a><div><h2 id=什么是图>什么是图</h2><p>图模拟一组链接，图由顶点和边组成。一个顶点可能与众多顶点直接相连，这些顶点被称为<strong>邻居</strong>。</p><p>图通常表示为：<code>G(V,E)</code>，其中，<code>G</code>表示一个图，<code>V</code>是图中顶点的集合，<code>E</code>是图中边的集合。</p><h4 id=简单图>简单图</h4><p>在图结构中，若不存在顶点到其自身的边，且同一条边不重复出现，则这样的图称之为简单图。</p><h4 id=无向图>无向图</h4><p>如果图中任意两个顶点之间的边都是无向边，则称该图为无向图。</p><p>无向边：若顶点 M 到顶点 N 的边没有方向，称这条边为无向边，用无序偶对(M,N)或(N,M)表示。</p><a href=https://www.vimiix.com/posts/2018-06-03-grokking-algorithms-chapter-6/>Read more...</a></div></article><article><h1><a href=https://www.vimiix.com/posts/2018-06-02-grokking-algorithms-chapter-5/>《算法图解》读书笔记5-散列函数及扩展</a></h1><b><time>2018.06.02 16:20</time></b>
<a href=/tags/algorithms>algorithms</a>
<a href=/tags/linux>Linux</a><div><h2 id=散列函数>散列函数</h2><p>散列函数就是一种<strong>映射</strong>，是从关键字到存储地址的映射。通常，包含散列函数的算法的算法复杂度都为 O(1)，对应到 Python 中的数据结构就是字典，给一个 key 可以得到一个固定的 value 值。散列函数必须满足一些要求：</p><ul><li>它必须是一直的。例如，假设输入 apple 时得到的是 4，那么每次输入 apple 时，都必须是 4，不然这个散列函数就是无意义的；</li><li>散列函数应该将不同的输入值，对应到不同的值上。（虽然不同的 key 对应相同的 value 是允许的，但最理想的情况是不同的 key，对应不同的 value，这种称之为<a href=https://zh.wikipedia.org/wiki/%E5%AE%8C%E7%BE%8E%E6%95%A3%E5%88%97>完美散列</a>）</li></ul><a href=https://www.vimiix.com/posts/2018-06-02-grokking-algorithms-chapter-5/>Read more...</a></div></article><div><a href=/>上一页</a>
2 of 5
<a href=/page/3/>下一页</a></div></main><footer><p>Social Links:
<a href=https://github.com/vimiix><b>Github</b></a>.
<a href=https://www.douban.com/people/vimiix/><b>Douban</b></a>.
<a href=mailto:i@vimiix.com><b>Email</b></a>.<br><hr>&copy; 2017-2025
Vimiix Yao; All rights reserved.
<a href=https://beian.miit.gov.cn/>京ICP备19015214号-1</a></p><script src=https://l2dwidget.js.org/lib/L2Dwidget.min.js></script><script>L2Dwidget.init({model:{jsonPath:"https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json"}})</script></footer></body></html>